package com.jstyle.blesdk.Util;


import android.text.TextUtils;
import android.util.Log;

import com.jstyle.blesdk.callback.DataListener;
import com.jstyle.blesdk.cmdenum.SendCmdState;
import com.jstyle.blesdk.constant.DeviceConst;
import com.jstyle.blesdk.constant.DeviceKey;

import com.jstyle.blesdk.model.AutomicHeart;
import com.jstyle.blesdk.model.Clock;
import com.jstyle.blesdk.model.ControlHRV;
import com.jstyle.blesdk.model.DeviceBaseParameter;
import com.jstyle.blesdk.model.DeviceID;
import com.jstyle.blesdk.model.DeviceName;
import com.jstyle.blesdk.model.ExerciseMode;
import com.jstyle.blesdk.model.GetData;
import com.jstyle.blesdk.model.MotSign;
import com.jstyle.blesdk.model.Notifier;
import com.jstyle.blesdk.model.Notifier1790;
import com.jstyle.blesdk.model.Notifier1810;
import com.jstyle.blesdk.model.PersonalGoal;
import com.jstyle.blesdk.model.SendData;
import com.jstyle.blesdk.model.SetPersonalInfo;
import com.jstyle.blesdk.model.SetTime;
import com.jstyle.blesdk.model.SportPeriod;
import com.jstyle.blesdk.model.StepModel;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2018/4/9.
 */

public class SingleDealData {


    public static byte[] sendData(SendCmdState sendCmdState, SendData sendData) {
        byte[] value = null;
        switch (sendCmdState) {
            case GET_SPORTMODEL_DATA:
                value=GetSportData((GetData) sendData);
                break;
            case GET_GPS_DATA:
                value=GetGpsData((GetData) sendData);
                break;
            case SEND_DEVICE_Time:
                value = setDeviceTime(sendData);
                break;
            case GET_DEVICE_Time:
                value = getDeviceTime();
                break;
            case SET_PERSONAL_INFO:
                value = setInfo(sendData);
                break;
            case GET_PERSONAL_INFO:
                value = getInfo();
                break;
            case SET_DEVICE_INFO:
                value = setDeviceInfo(sendData);
                break;
            case Disable_Ancs:
                value = disableAncs();
                break;
            case GET_DEVICE_INFO:
                value = getDeviceInfo();
                break;
            case SET_DEVICE_ID:
                value = setDeviceId((DeviceID) sendData);
                break;
            case SET_STEP_MODEL:
                value = setStepModel((StepModel) sendData);
                break;
            case SET_GOAL:
                value = SetGoal((PersonalGoal) sendData);
                break;
            case GET_GOAL:
                value = GetGoal();
                break;
            case READ_DEVICE_BATTERY:
                value = GetBatteryLevel();
                break;
            case READ_MAC_ADDRESS:
                value = GetMacAddress();
                break;
            case READ_VERSION:
                value = getVersion();
                break;
            case SET_FACTORY:
                value = reset();
                break;
            case SET_MCU_MODEL:
                value = MCUReset();
                break;
            case SET_MOT_SIGN:
                value = setMotSign((MotSign) sendData);
                break;
            case SET_DEVICE_NAME:
                value = SetDeviceName((DeviceName) sendData);
                break;
            case GET_DEVICE_NAME:
                value = GetDeviceName();
                break;
            case SET_AUTOMIC_HEART:
                value = SetAutoHeartZone((AutomicHeart) sendData);
                break;
            case GET_AUTOMIC_HEART:
                value = GetAutoHeartZone();
                break;
            case SET_ALARM:
                value = setClock((Clock) sendData);
                break;
            case SET_NOTIFIER:
                value = setNotifyData((Notifier) sendData);
                break;
            case SET_SPORT_PERIOD:
                value = setActivityAlarm((SportPeriod) sendData);
                break;
            case READ_SPORT_PERIOD:
                value = getActivityAlarm();
                break;
            case GET_STEP_DATA:
                value = getTotalDataWithDay((GetData) sendData);
                break;
            case GET_STEP_DETAIL:
                value = getDetailDataWithDay((GetData) sendData);
                break;
            case GET_SLEEP_DETAIL:
                value = getSleepData((GetData) sendData);
                break;
            case GET_HEART_DATA:
                value = GetHeartRateData((GetData) sendData);
                break;
            case GET_ONCE_HEARTDATA:
                value = GetOnceHeartRateData((GetData) sendData);
                break;
            case GET_HRV_DATA:
                value = GetHRVTestData((GetData) sendData);
                break;
            case GET_ALARM:
                value = readClock((GetData) sendData);
                break;
            case HRV_CONTROL_MODEL:
                value = HRVData((ControlHRV) sendData);
                break;
            case Set_EXERCISE_MODE:
                value=setExerciseMode((ExerciseMode) sendData);
                break;
            case ENABLE_ECGPPG:
                value=enableEcgPPg(4);
                break;
            case STOP_ECGPPG:
                value=stopEcgPPg();

                break;
//            case GET_HRV_TESTDATA:
//                break;
        }
        return value;
    }

    private static byte[] enableEcgPPg(int level){
        byte[] value = new byte[16];
        value[0]=DeviceConst.CMD_Enable_ECGPPG;
        value[1]= (byte) level;
        crcValue(value);
        return value;
    }
    private static byte[] stopEcgPPg(){
        byte[] value = new byte[16];
        value[0]=DeviceConst.CMD_STOP_ECGPPG;
        crcValue(value);
        return value;
    }
    private static final String TAG = "SingleDealData";
    public static byte[]deleteAllClock(){
       byte[] value = new byte[16];
       value[0]=0x57;
       value[1]= (byte) 0x99;
       crcValue(value);
       return value;
    }
    public static byte[] setClockData(List<Clock>clockList){
        int size=clockList.size();
        int length=39;
        byte[]totalValue=new byte[length*size+2];
        for(int i=0;i<clockList.size();i++){
            Clock clock=clockList.get(i);
            byte[] value = new byte[length];
            String content = clock.getContent();
            byte[] infoValue = getInfoValue(content, 30);
            value[0] = DeviceConst.CMD_Set_Clock;
            value[1]= (byte) size;
            value[2]= (byte) clock.getNumber();
            value[3] = (byte) (clock.isEnable()?1:0);;
            value[4] = (byte) clock.getType();
            value[5] = ResolveUtil.getTimeValue(clock.getHour());
            value[6] = ResolveUtil.getTimeValue(clock.getMinute());
            value[7] = (byte) clock.getWeek();
            value[8] = (byte) (infoValue.length==0?1:infoValue.length);
            System.arraycopy(infoValue, 0, value, 9, infoValue.length);
            System.arraycopy(value, 0, totalValue, i*length, value.length);
        }
        Log.i(TAG, "setClockData: "+totalValue.length);
        totalValue[totalValue.length-2]=DeviceConst.CMD_Set_Clock;
        totalValue[totalValue.length-1]= (byte) 0xff;
        return totalValue;
    }

    private static byte[] setExerciseMode(ExerciseMode sendData) {
        byte[] value = new byte[16];
        value[0]=DeviceConst.CMD_Start_EXERCISE;
        value[1]= (byte) sendData.getEnableStatus();
        value[2]= (byte) sendData.getExerciseMode();
        crcValue(value);
        return value;
    }


    public static byte[] sendData(SendCmdState sendCmdState) {
        byte[] value = null;
        switch (sendCmdState) {
            case Back_HOME:
                value=getHome();
                break;
            case Enter_Carmera:
                value=enterCarmera();
                break;
            case ENABLE_GPS:
                value=enableGps();
                break;
            case Disable_Ancs:
                value=disableAncs();
            break;
            case DISABLE_GPS:
                value=disableGps();
                break;
            case GET_DEVICE_Time:
                value = getDeviceTime();
                break;
            case Enter_DfuMode:
                value=startOTA();
                break;
            case GET_PERSONAL_INFO:
                value = getInfo();
                break;
            case GET_DEVICE_INFO:
                value = getDeviceInfo();
                break;
            case GET_GOAL:
                value = GetGoal();
                break;
            case READ_DEVICE_BATTERY:
                value = GetBatteryLevel();
                break;
            case READ_MAC_ADDRESS:
                value = GetMacAddress();
                break;
            case READ_VERSION:
                value = getVersion();
                break;
            case SET_FACTORY:
                value = reset();
                break;
            case SET_MCU_MODEL:
                value = MCUReset();
                break;
            case GET_DEVICE_NAME:
                value = GetDeviceName();
                break;
            case GET_AUTOMIC_HEART:
                value = GetAutoHeartZone();
                break;
            case SET_NOTIFIER:
                break;
            case READ_SPORT_PERIOD:
                value = getActivityAlarm();
                break;
            case ENABLE_ECGPPG:
                value=enableEcgPPg(4);
                break;
            case STOP_ECGPPG:
                value=stopEcgPPg();

                break;
        }
        return value;
    }



    public static void receiveUpdateValue(byte[] value, DataListener dataListener) {
        Map<String, String> map = new HashMap<>();
        List<Map<String, String>> list = new ArrayList<>();
        switch (value[0]) {
            case DeviceConst.CMD_EnterEcg:
                dataListener.dataCallback(map,SendCmdState.EnterEcg);
                break;
            case DeviceConst.CMD_Start_EXERCISE:
                map.put(DeviceKey.KEnable_exercise,ResolveUtil.getValue(value[1],0)+"");
                dataListener.dataCallback(map,SendCmdState.Set_EXERCISE_MODE);
                break;
            case DeviceConst.cmdCheck:
                map.put(DeviceKey.KGpsResCheck0,ResolveUtil.getValue(value[1],0)+"");
                map.put(DeviceKey.KGpsResCheck1,ResolveUtil.getValue(value[2],0)+"");
                dataListener.dataCallback(map,SendCmdState.CHECK_RESUPDATE);
                break;
            case DeviceConst.CMD_FUNCATION:
                dataListener.dataCallback(ResolveUtil.function(value),SendCmdState.Function);
                break;
            case DeviceConst.CMD_sos:
                dataListener.dataCallback(new HashMap<String, String>(),SendCmdState.Sos);
                break;
            case DeviceConst.CMD_ENABLE_GPS:
                if(value.length==16)return;
                dataListener.dataCallback(ResolveUtil.getActivityGpsData(value),SendCmdState.ACTIVITY_GPS_DATA);
                break;
            case  DeviceConst.CMD_EXERCISE_DATA:
                dataListener.dataCallback(ResolveUtil.getActivityExerciseData(value),SendCmdState.ACTIVITY_EXERCISE_DATA);
                break;
            case DeviceConst.CMD_SET_TIME:
                dataListener.dataCallback(ResolveUtil.setTimeSuccessful(value),SendCmdState.SEND_DEVICE_Time);

                break;
            case DeviceConst.CMD_Result_ECGPPG:
                dataListener.dataCallback(ResolveUtil.getEcgPPGResult(value), SendCmdState.ResultEcg);
                break;
            case DeviceConst.CMD_Get_GPSDATA:
                dataListener.dataCallback(ResolveUtil.getHistoryGpsData(value),SendCmdState.GET_GPS_DATA);

                break;
            case DeviceConst.CMD_Get_SPORTData:
                dataListener.dataCallback(ResolveUtil.getExerciseData(value),SendCmdState.GET_SPORTMODEL_DATA);
                break;
            case DeviceConst.CMD_GET_TIME:
                map.put(DeviceKey.KDeviceTime, ResolveUtil.getDeviceTime(value));
                map.put(DeviceKey.KGpsTime, ResolveUtil.getGpsTime(value));
                map.put(DeviceKey.KPhoneDataLength, ResolveUtil.getValue(value[8],0)+"");

                map.put(DeviceKey.KTimeZone, ResolveUtil.getValue(value[13],0)+"");
                Log.i(TAG, "receiveUpdateValue: "+ResolveUtil.getValue(value[13],0));
                dataListener.dataCallback(map, SendCmdState.GET_DEVICE_Time);
                break;
            case DeviceConst.CMD_GET_USERINFO:
                String[] userInfo = ResolveUtil.getUserInfo(value);
                map.put(DeviceKey.KUserSex, userInfo[0]);
                map.put(DeviceKey.KUserAge, userInfo[1]);
                map.put(DeviceKey.KUserHeight, userInfo[2]);
                map.put(DeviceKey.KUserWeight, userInfo[3]);
                map.put(DeviceKey.KUserStepLenght, userInfo[4]);
                map.put(DeviceKey.KUserDeviceId, userInfo[5]);
                dataListener.dataCallback(map, SendCmdState.GET_PERSONAL_INFO);
                break;
            case DeviceConst.CMD_Get_DeviceInfo:
                String[] deviceInfo = ResolveUtil.getDeviceInfo(value);
                map.put(DeviceKey.KDistanceUnit, deviceInfo[0]);
                map.put(DeviceKey.KHourState, deviceInfo[1]);
                map.put(DeviceKey.KHandleEnable, deviceInfo[2]);
                map.put(DeviceKey.KHandleSign, deviceInfo[3]);
                map.put(DeviceKey.KScreenState, deviceInfo[4]);
                map.put(DeviceKey.KANCSEnable, deviceInfo[5]);
                map.put(DeviceKey.KBaseHeart, deviceInfo[6]);
                map.put(DeviceKey.KBrightnessLevel, deviceInfo[7]);
                dataListener.dataCallback(map, SendCmdState.GET_DEVICE_INFO);
                break;
            case DeviceConst.CMD_Enable_Activity:
                if(value.length!=ResolveUtil.activityLength)return;
                String[] activityData = ResolveUtil.getActivityData(value);
                map.put(DeviceKey.KTotalSteps, activityData[0]);
                map.put(DeviceKey.KCalories, activityData[1]);
                map.put(DeviceKey.KDistance, activityData[2]);
                map.put(DeviceKey.KSportTime, activityData[3]);
                map.put(DeviceKey.KHeartValue, activityData[4]);
                map.put(DeviceKey.KExerciseTime, activityData[5]);
                dataListener.dataCallback(map, SendCmdState.SET_STEP_MODEL);
                break;
            case DeviceConst.CMD_Get_Goal:
                String goal = ResolveUtil.getGoal(value);
                map.put(DeviceKey.KStepGoal, goal);
                dataListener.dataCallback(map, SendCmdState.GET_GOAL);
                break;
            case DeviceConst.CMD_Get_BatteryLevel:
                String battery = ResolveUtil.getDeviceBattery(value);
                map.put(DeviceKey.KBattery, battery);
                dataListener.dataCallback(map, SendCmdState.READ_DEVICE_BATTERY);
                break;
            case DeviceConst.CMD_Get_Address:
                String address = ResolveUtil.getDeviceAddress(value);
                map.put(DeviceKey.KMacAddress, address);
                dataListener.dataCallback(map, SendCmdState.READ_MAC_ADDRESS);
                break;
            case DeviceConst.CMD_Get_Version:
                String version = ResolveUtil.getDeviceVersion(value);
                map.put(DeviceKey.KVersion, version);
                dataListener.dataCallback(map, SendCmdState.READ_VERSION);
                break;
            case DeviceConst.CMD_Get_Name:
                String deviceName = ResolveUtil.getDeviceName(value);
                map.put(DeviceKey.KDeviceName, deviceName);
                dataListener.dataCallback(map, SendCmdState.GET_DEVICE_NAME);
                break;
            case DeviceConst.CMD_Get_AutoHeart:
                String[] autoHeart = ResolveUtil.getAutoHeart(value);
                map.put(DeviceKey.KWorkModel, autoHeart[0]);
                map.put(DeviceKey.KHeartStartHour, autoHeart[1]);
                map.put(DeviceKey.KHeartStartMinter, autoHeart[2]);
                map.put(DeviceKey.KHeartEndHour, autoHeart[3]);
                map.put(DeviceKey.KHeartEndMinter, autoHeart[4]);
                map.put(DeviceKey.KHeartWeek, autoHeart[5]);
                map.put(DeviceKey.KWorkTime, autoHeart[6]);
                dataListener.dataCallback(map, SendCmdState.GET_AUTOMIC_HEART);
                break;
            case DeviceConst.CMD_Get_ActivityAlarm:
                String[] activityAlarm = ResolveUtil.getActivityAlarm(value);
                map.put(DeviceKey.KSportStartHour, activityAlarm[0]);
                map.put(DeviceKey.KSportStartMinter, activityAlarm[1]);
                map.put(DeviceKey.KSportEndHour, activityAlarm[2]);
                map.put(DeviceKey.KSportEndMinter, activityAlarm[3]);
                map.put(DeviceKey.KSportWeekEnable, activityAlarm[4]);
                map.put(DeviceKey.KSportNotifierTime, activityAlarm[5]);
                map.put(DeviceKey.KSportMinStep, activityAlarm[6]);
                dataListener.dataCallback(map, SendCmdState.READ_SPORT_PERIOD);
                break;
            case DeviceConst.CMD_Get_TotalData:
                dataListener.dataCallback(ResolveUtil.getTotalStepData(value),
                        SendCmdState.GET_STEP_DATA);
                break;
            case DeviceConst.CMD_Get_DetailData:
                dataListener.dataCallback(ResolveUtil.getDetailData(value), SendCmdState.GET_STEP_DETAIL);
                break;
            case DeviceConst.CMD_Get_SleepData:
                dataListener.dataCallback(ResolveUtil.getSleepData(value), SendCmdState.GET_SLEEP_DETAIL);
                break;
            case DeviceConst.CMD_Get_HeartData:
                dataListener.dataCallback(ResolveUtil.getHeartData(value), SendCmdState.GET_HEART_DATA);
                break;
            case DeviceConst.CMD_Get_OnceHeartData:
                dataListener.dataCallback(ResolveUtil.getOnceHeartData(value), SendCmdState.GET_ONCE_HEARTDATA);
                break;
            case DeviceConst.CMD_Get_HrvTestData:
                dataListener.dataCallback(ResolveUtil.getHrvTestData(value), SendCmdState.GET_HRV_DATA);
                break;
            case DeviceConst.CMD_Get_Clock:
                dataListener.dataCallback(ResolveUtil.getClockData(value), SendCmdState.GET_ALARM);
                break;
            case DeviceConst.CMD_Set_Clock:
                dataListener.dataCallback(ResolveUtil.updateClockSuccessful(value), SendCmdState.SET_ALARM);
                break;
            case DeviceConst.CMD_Get_HrvTestResultData:
                int len = value.length;
                for (int i = 1; i < len; i += 0) {
                    int length = value[i + 1] + 2;
                    switch (value[i]) {
                        case 1:
                            int labBloodTest_Progress = ResolveUtil.getValue(value[i + 2], 0);
                            int labBloodTest_PPGHeigth = ResolveUtil.getValue(value[i + 3], 0) + ResolveUtil.getValue(value[i + 4], 1);
                            int labBloodTest_WaveWidth = ResolveUtil.getValue(value[i + 5], 0) + ResolveUtil.getValue(value[i + 6], 1);
                            map.put(DeviceKey.KBloodTestProgress, String.valueOf(labBloodTest_Progress));
                            map.put(DeviceKey.KBloodTestValue, String.valueOf(labBloodTest_PPGHeigth));
                            map.put(DeviceKey.KBloodTestCurve, String.valueOf(labBloodTest_WaveWidth));

                            break;
                        case 2:
                            int labBloodReslut_ReboundPercent = ResolveUtil.getValue(value[i + 2], 0);
                            int labBloodResult_ReboundHeigth = ResolveUtil.getValue(value[i + 3], 0) + ResolveUtil.getValue(value[i + 4], 1);
                            int labBloodResult_MaxHeigth = ResolveUtil.getValue(value[i + 5], 0) + ResolveUtil.getValue(value[i + 6], 1);
                            int labBloodResult_Level = ResolveUtil.getValue(value[i + 7], 0);
                            map.put(DeviceKey.KBloodResultPercent, String.valueOf(labBloodReslut_ReboundPercent));
                            map.put(DeviceKey.KBloodResultRebound, String.valueOf(labBloodResult_ReboundHeigth));
                            map.put(DeviceKey.KBloodResultMax, String.valueOf(labBloodResult_MaxHeigth));
                            map.put(DeviceKey.KBloodResultRank, String.valueOf(labBloodResult_Level));

                            break;
                        case 3:
                            int labHRVTest_Progress = ResolveUtil.getValue(value[i + 2], 0);
                            int labHRVTest_HeartRateWidth = ResolveUtil.getValue(value[i + 3], 0) + ResolveUtil.getValue(value[i + 4], 1);
                            int labHRV_HeartRate = ResolveUtil.getValue(value[i + 5], 0);
                            map.put(DeviceKey.KHrvTestProgress, String.valueOf(labHRVTest_Progress));
                            map.put(DeviceKey.KHrvTestWidth, String.valueOf(labHRVTest_HeartRateWidth));
                            map.put(DeviceKey.KHrvTestValue, String.valueOf(labHRV_HeartRate));

                            break;
                        case 4: {
                            int labHRVResult_SDNN = ResolveUtil.getValue(value[i + 2], 0) + ResolveUtil.getValue(value[i + 3], 1);
                            int labHRVResult_AvgSDNN = ResolveUtil.getValue(value[i + 4], 0) + ResolveUtil.getValue(value[i + 5], 1);
                            int labHRVResult_TotalSDNN = ResolveUtil.getValue(value[i + 6], 0) + ResolveUtil.getValue(value[i + 7], 1);
                            int labHRVResult_Count = ResolveUtil.getValue(value[i + 8], 0);
                            int labHRVResult_Pilao = ResolveUtil.getValue(value[i + 9], 0);
                            int labHRVResult_HeartRate = ResolveUtil.getValue(value[i + 10], 0);
                            map.put(DeviceKey.KHrvResultState, String.valueOf(labHRVResult_SDNN));
                            map.put(DeviceKey.KHrvResultAvg, String.valueOf(labHRVResult_AvgSDNN));
                            map.put(DeviceKey.KHrvResultTotal, String.valueOf(labHRVResult_TotalSDNN));
                            map.put(DeviceKey.KHrvResultCount, String.valueOf(labHRVResult_Count));
                            map.put(DeviceKey.KHrvResultTired, String.valueOf(labHRVResult_Pilao));
                            map.put(DeviceKey.KHrvResultValue, String.valueOf(labHRVResult_HeartRate));

                        }
                        break;
                        case 5: {
                            int seg_Activity = ResolveUtil.getValue(value[i + 2], 0);
                            map.put(DeviceKey.KDisturbState, String.valueOf(seg_Activity));

                        }
                        break;
                        case 6: {
                            int seg_Wear = ResolveUtil.getValue(value[i + 2], 0);
                            map.put(DeviceKey.KSlipHand, String.valueOf(seg_Wear));

                        }
                        break;
                        case 0x0a: {
                            StringBuffer stringBuffer = new StringBuffer();
                            for (int j = 0; j < length - 2; j += 2) {
                                int PPG = ResolveUtil.getValue(value[j], 0) + ResolveUtil.getValue(value[j + 1], 1);
                                if (PPG > 32768)
                                    PPG = (PPG - 65536);
                                stringBuffer.append(PPG).append(",");
                            }
                            String ppg = stringBuffer.toString();
                            map.put(DeviceKey.KPPGData, ppg.substring(0, ppg.length() - 1));
                        }
                        break;
                        case 0x0b: {

                        }
                        break;
                        default:
                            break;
                    }
                    i += length;
                }
                dataListener.dataCallback(map, SendCmdState.GET_HRV_TESTDATA);
                break;
        }
        //  return map;
    }


    private static byte[] getSleepData(GetData sendData) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_SleepData;
        value[1] = (byte) sendData.getDataNum();
        crcValue(value);
        return value;
    }

    private static byte[] setMotSign(MotSign motSign) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Set_MOT_SIGN;
        value[1] = (byte) motSign.getMotValue();
        crcValue(value);
        return value;
    }

    private static byte[] setStepModel(StepModel stepModel) {
        byte[] value = new byte[16];
        value = stepModel.isStepState() ? startGo() : stopGo();
        return value;
    }


    /**
     * 开始实时计步
     *
     * @return
     */
    private static byte[] startGo() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Enable_Activity;
        value[1] = 1;
        crcValue(value);
        return value;
    }


    /**
     * 停止实时计步
     *
     * @return
     */
    private static byte[] stopGo() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Enable_Activity;
        value[1] = 0;
        crcValue(value);
        return value;
    }
    private static byte[] enableGps() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_ENABLE_GPS;
        value[1] = 1;
        crcValue(value);
        return value;
    }
    private static byte[] disableGps() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_ENABLE_GPS;
        value[1] = 0;
        crcValue(value);
        return value;
    }

    /**
     * 设置个人信息
     *
     * @param
     * @return
     */
    private static byte[] setInfo(SendData sendData) {
        byte[] value = new byte[16];
        if (sendData instanceof SetPersonalInfo) {
            SetPersonalInfo info = (SetPersonalInfo) sendData;
            int male = info.getSex();
            int age = info.getAge();
            int height = info.getHeight();
            int weight = info.getWeight();
            int stepLength = info.getStepLength();
            value[0] = DeviceConst.CMD_Set_UseInfo;
            value[1] = (byte) male;
            value[2] = (byte) age;
            value[3] = (byte) height;
            value[4] = (byte) weight;
            value[5] = (byte) stepLength;
            crcValue(value);
        }
        return value;
    }


    /**
     * 获取个人信息
     *
     * @return
     */
    private static byte[] getInfo() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_GET_USERINFO;
        crcValue(value);
        return value;
    }


    /**
     * 设置设备时间
     *
     * @param
     * @return
     */
    private static byte[] setDeviceTime(SendData sendData) {
        byte[] value = new byte[16];
        float timeZone=ResolveUtil.getCurrentTimeZone();
        int zoneValue= (int) (timeZone*60);
        value[9] = (byte) ((Math.abs(zoneValue) >> 8) & 0xff);
        value[8] = (byte) ((Math.abs(zoneValue)) & 0xff);
        if(zoneValue>0){
           value[9]= (byte) (value[9]+0x80);
        }
        if (sendData instanceof SetTime) {
            SetTime time = (SetTime) sendData;
            int year = time.getYear();
            int month = time.getMonth();
            int day = time.getDay();
            int hour = time.getHour();
            int min = time.getMinute();
            int second = time.getSecond();
            value[0] = DeviceConst.CMD_SET_TIME;
            value[1] = ResolveUtil.getTimeValue(year);
            value[2] = ResolveUtil.getTimeValue(month);
            value[3] = ResolveUtil.getTimeValue(day);
            value[4] = ResolveUtil.getTimeValue(hour);
            value[5] = ResolveUtil.getTimeValue(min);
            value[6] = ResolveUtil.getTimeValue(second);

            crcValue(value);
        }
        return value;
    }


    /**
     * 获取设备时间
     *
     * @return
     */
    private static byte[] getDeviceTime() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_GET_TIME;
        crcValue(value);
        return value;
    }



    /**
     * 99: 删除步数详细数据 ,
     * 0:读最近的步数详细数据。
     * 1：读指定位置的步数详细数据。
     * 2：继续上次读的位置下一段数据
     *
     * @param
     * @return
     */
    private static byte[] getDetailDataWithDay(GetData getData) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_DetailData;
        value[1] = (byte) getData.getDataNum();
        crcValue(value);
        return value;
    }


    /**
     * 获取某天总数据
     *
     * @param
     * @return
     */
    private static byte[] getTotalDataWithDay(GetData getData) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_TotalData;
        value[1] = (byte) getData.getDataNum();
        crcValue(value);
        return value;
    }


    /**
     * 进入dfu模式
     *
     * @return
     */
    private static byte[] startOTA() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Start_Ota;
        crcValue(value);
        return value;

    }


    /**
     * 获取设备版本号
     *
     * @return
     */
    private static byte[] getVersion() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_Version;
        crcValue(value);
        return value;
    }


    /**
     * 读取闹钟 99删除闹钟，0读取闹钟
     *
     * @param getData
     * @return
     */
    private static byte[] readClock(GetData getData) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_Clock;
        value[1] = (byte) getData.getDataNum();
        crcValue(value);
        return value;
    }


    /**
     * 设置闹钟
     *
     * @param clock
     * @return
     */
    private static byte[] setClock(Clock clock) {
        byte[] value = new byte[37];
        String content = clock.getContent();
        byte[] infoValue = getInfoValue(content, 30);
        value[0] = DeviceConst.CMD_Set_Clock;
        value[1] = (byte) clock.getNumber();
        value[2] = (byte) clock.getType();
        value[3] = ResolveUtil.getTimeValue(clock.getHour());
        value[4] = ResolveUtil.getTimeValue(clock.getMinute());
        value[5] = (byte) clock.getWeek();
        value[6] = (byte) infoValue.length;
        System.arraycopy(infoValue, 0, value, 7, infoValue.length);
        return value;

    }


    /**
     * 设置运动提醒
     *
     * @param activityAlarm
     * @return
     */
    private static byte[] setActivityAlarm(SportPeriod activityAlarm) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Set_ActivityAlarm;
        value[1] = ResolveUtil.getTimeValue(activityAlarm.getStartHour());
        value[2] = ResolveUtil.getTimeValue(activityAlarm.getStartMinute());
        value[3] = ResolveUtil.getTimeValue(activityAlarm.getEndHour());
        value[4] = ResolveUtil.getTimeValue(activityAlarm.getEndMinute());
        value[5] = (byte) activityAlarm.getWeek();
        value[6] = (byte) activityAlarm.getIntervalTime();
        value[7] = (byte) (activityAlarm.getLeastStep() & 0xff);
        value[8]= (byte) (activityAlarm.isEnable()?1:0);
        crcValue(value);
        return value;
    }


    /**
     * 获取运动提醒
     *
     * @return
     */
    private static byte[] getActivityAlarm() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_ActivityAlarm;
        crcValue(value);
        return value;
    }


    /**
     * 恢复出厂设置
     *
     * @return
     */
    private static byte[] reset() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Reset;
        crcValue(value);
        return value;
    }


    /**
     * 获取设备mac地址
     *
     * @return
     */
    private static byte[] GetMacAddress() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_Address;
        crcValue(value);
        return value;
    }


    /**
     * 获取设备电量
     *
     * @return
     */
    private static byte[] GetBatteryLevel() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_BatteryLevel;
        crcValue(value);
        return value;
    }


    /**
     * 重启设备
     *
     * @return
     */
    private static byte[] MCUReset() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Mcu_Reset;
        crcValue(value);
        return value;
    }


    /**
     * 设置设备名字
     *
     * @param deviceName
     * @return
     */
    private static byte[] SetDeviceName(DeviceName deviceName) {
        byte[] value = new byte[16];
        String strName = deviceName.getName();
        value[0] = DeviceConst.CMD_Set_Name;
        int length = strName.length() > 14 ? 14 : strName.length();
        for (int i = 0; i < length; i++) {
            value[i + 1] = (byte) strName.charAt(i);
        }
        crcValue(value);
        return value;
    }


    /**
     * 获取设备名字
     *
     * @return
     */
    private static byte[] GetDeviceName() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_Name;
        crcValue(value);
        return value;
    }


    /**
     * 设置距离单位
     *
     * @param unit
     * @return
     */
    private static byte[] SetDistanceUnit(int unit) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Set_DistanceMode;
        value[1] = (byte) unit;
        crcValue(value);
        return value;
    }


    /**
     * 获取距离单位
     *
     * @return
     */
    private static byte[] GetDistanceUnit() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_DistanceMode;
        crcValue(value);
        return value;
    }


    /**
     * 设置时间模式
     *
     * @param unit
     * @return
     */
    private static byte[] SetTimeModeUnit(int unit) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Set_TimeMode;
        value[1] = (byte) unit;
        crcValue(value);
        return value;
    }


    /**
     * 获取时间模式
     *
     * @return
     */
    private static byte[] GetTimeMode() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_TimeMode;
        crcValue(value);
        return value;
    }


    /**
     * 获取屏幕模式
     *
     * @return
     */
    private static byte[] GetScreenMode() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_ScreenMode;
        crcValue(value);
        return value;
    }


    /**
     * 设置屏幕模式
     *
     * @param ScreenMode
     * @return
     */
    private static byte[] SetScreenMode(int ScreenMode) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Set_ScreenMode;
        value[1] = (byte) ScreenMode;
        crcValue(value);
        return value;
    }


    private static byte[] HRVData(ControlHRV controlHRV) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Enable_Hrv;
        value[1] = (byte) (controlHRV.isHrvState() ? 1 : 0);
        crcValue(value);
        return value;
    }


    private static byte[] BloodData(int BloodMode) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Enable_Blood;
        value[1] = (byte) BloodMode;
        crcValue(value);
        return value;
    }


    private static byte[] PPGWave(int PPGMode) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Enable_PPG;
        value[1] = (byte) PPGMode;
        crcValue(value);
        return value;
    }


    private static byte[] GetHeartAndBloodPressureHistoryData() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_HeartAndBloodHistory;
        crcValue(value);
        return value;
    }


    private static byte[] GetHRVTestData(GetData sendData) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_HrvTestData;
        value[1] = (byte) sendData.getDataNum();
        crcValue(value);
        return value;
    }


    private static byte[] GetBloodHistoryData() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_BloodHistory;
        crcValue(value);
        return value;
    }


    private static byte[] DeleteHistoryDataWithDay(int day) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_DeleteData;
        value[1] = (byte) day;
        crcValue(value);
        return value;
    }


//    private static byte[] ReadHistoryGoalWithDay(int day) {
//
//    }


    private static byte[] SetBaseHeartRate(int BaseHeartRate) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Set_BaseHeartRateVale;
        value[1] = (byte) BaseHeartRate;
        crcValue(value);
        return value;
    }


    private static byte[] GetBaseHeartRate() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_BaseHeartRateVale;
        crcValue(value);
        return value;
    }


    private static byte[] SetAutoHeartZone(AutomicHeart autoHeart) {
        byte[] value = new byte[16];
        int time = autoHeart.getTime();
        value[0] = DeviceConst.CMD_Set_AutoHeart;
        value[1] = (byte) autoHeart.getOpen();
        value[2] = ResolveUtil.getTimeValue(autoHeart.getStartHour());
        value[3] = ResolveUtil.getTimeValue(autoHeart.getStartMinute());
        value[4] = ResolveUtil.getTimeValue(autoHeart.getEndHour());
        value[5] = ResolveUtil.getTimeValue(autoHeart.getEndMinute());
        value[6] = (byte) autoHeart.getWeek();
        value[7] = (byte) (time & 0xff);
        value[8] = (byte) ((time >> 8) & 0xff);
        crcValue(value);
        return value;
    }


    private static byte[] GetAutoHeartZone() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_AutoHeart;
        crcValue(value);
        return value;
    }


    private static byte[] StartHeartRateMode() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Enable_ActivityHeartRate;
        value[1] = 1;
        crcValue(value);
        return value;
    }


    private static byte[] StopHeartRateMode() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Enable_ActivityHeartRate;
        value[1] = 0;
        crcValue(value);
        return value;
    }


    private static byte[] SetHeartRateDataMode(int DataMode) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Set_ActivityHeartRateMode;
        value[1] = (byte) DataMode;
        crcValue(value);
        return value;
    }


    private static byte[] GetHeartRateData(GetData getData) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_HeartData;
        value[1] = (byte) getData.getDataNum();
        crcValue(value);
        return value;
    }
    private static byte[] GetGpsData(GetData getData) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_GPSDATA;
        value[1] = (byte) getData.getDataNum();
        crcValue(value);
        return value;
    }
    private static byte[] GetSportData(GetData getData) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_SPORTData;
        value[1] = (byte) getData.getDataNum();
        crcValue(value);
        return value;
    }

    private static byte[] GetOnceHeartRateData(GetData getData) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_OnceHeartData;
        value[1] = (byte) getData.getDataNum();
        crcValue(value);
        return value;
    }

    private static byte[] ReadHistoryHeartRateWithNumber(int Number) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_HeartRateHistory;
        value[1] = (byte) Number;
        crcValue(value);
        return value;
    }


    private static byte[] SetGoal(PersonalGoal personalGoal) {
        byte[] value = new byte[16];
        int goal = personalGoal.getStepGoal();
        value[0] = DeviceConst.CMD_Set_Goal;
        value[4] = (byte) ((goal >> 24) & 0xff);
        value[3] = (byte) ((goal >> 16) & 0xff);
        value[2] = (byte) ((goal >> 8) & 0xff);
        value[1] = (byte) ((goal) & 0xff);
        crcValue(value);
        return value;
    }


    private static byte[] GetGoal() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_Goal;
        crcValue(value);
        return value;
    }


    private static byte[] setDeviceId(DeviceID deviceID) {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Set_DeviceID;
        String deviceId = String.valueOf(deviceID.getDeviceID());
        for (int i = 0; i < 6; i++) {
            value[i + 1] = (byte) deviceId.charAt(i);
        }
        crcValue(value);
        return value;
    }

    private static byte[] setDeviceInfo(SendData sendData) {
        byte[] value = new byte[16];
        if (sendData instanceof DeviceBaseParameter) {
            DeviceBaseParameter deviceBaseParameter = (DeviceBaseParameter) sendData;
            value[0] = DeviceConst.CMD_Set_DeviceInfo;
            value[1] = (byte) (deviceBaseParameter.isDistanceUnit() ? 0x81 : 0x80);
            value[2] = (byte) (deviceBaseParameter.isShowHour() ? 0x81 : 0x80);
            value[3] = (byte) (deviceBaseParameter.isRainHandEnable() ? 0x81 : 0x80);
            value[4] = (byte) (deviceBaseParameter.isHandleState() ? 0x81 : 0x80);
            value[5] = (byte) (deviceBaseParameter.isScreenState() ? 0x81 : 0x80);
            value[9] = (byte) deviceBaseParameter.getBaseHeart();
            value[11] = (byte) (0x80+deviceBaseParameter.getBrightnessLevel());
            crcValue(value);
        }
        return value;
    }
    private static byte[] disableAncs() {
        byte[] value = new byte[16];
            value[0] = DeviceConst.CMD_Set_DeviceInfo;
            value[6]= (byte) 0x80;

            crcValue(value);
        return value;
    }

    private static byte[] getDeviceInfo() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.CMD_Get_DeviceInfo;
        crcValue(value);
        return value;
    }
    private static byte[] getHome() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.cmd_back_home;
        crcValue(value);
        return value;
    }

    private static byte[] setNotifyData(Notifier sendData) {
        if(sendData.getNotifierType() instanceof Notifier1790){
            String info = sendData.getInfo();
            String title=sendData.getTitle();
            byte[] infoValue =TextUtils.isEmpty(info)?new byte[1]: getInfoValue(info, 60);
            byte[] titleValue =TextUtils.isEmpty(title)?new byte[1]: getInfoValue(title, 60);
            // byte[] value = new byte[infoValue.length + 3];
            byte[] value = new byte[124];
            value[0] = DeviceConst.CMD_Notify;
            value[1] = (byte) sendData.getType();
            value[2] = (byte) infoValue.length;
            System.arraycopy(infoValue, 0, value, 3, infoValue.length);
            value[63]=(byte) titleValue.length;
            System.arraycopy(titleValue, 0, value, 64, titleValue.length);
            return value;
        }else{
            return  setNotifyData1810(sendData);
        }


    }
    private static byte[] setNotifyData1810(Notifier sendData) {
        String info = TextUtils.isEmpty(sendData.getInfo())?"":sendData.getInfo();
        String title=TextUtils.isEmpty(sendData.getTitle())?"":sendData.getTitle();
        String msg=title+":"+info;
        byte[] infoValue =TextUtils.isEmpty(info)?new byte[1]: getInfoValue(msg, 60);

        // byte[] value = new byte[infoValue.length + 3];
        byte[] value = new byte[124];
        value[0] = DeviceConst.CMD_Notify;
        value[1] = (byte) sendData.getType();
        value[2] = (byte) infoValue.length;
        System.arraycopy(infoValue, 0, value, 3, infoValue.length);

        return value;
    }

    private static byte[] enterCarmera() {
        byte[] value = new byte[16];
        value[0] = DeviceConst.cmd_Enter_Carmera;
        crcValue(value);
        return value;
    }
    public static byte[] getInfoValue(String info, int maxLength) {
        byte[] nameBytes = null;
        try {
            nameBytes = info.getBytes("UTF-8");
            if (nameBytes.length >= maxLength) {//两条命令总共32个字节，内容只占24个字节（32-2*（1cmd+1消息类型+1长度+1校验））
                byte[] real = new byte[maxLength];
                char[] chars = info.toCharArray();
                int length = 0;
                for (int i = 0; i < chars.length; i++) {
                    String s = String.valueOf(chars[i]);
                    byte[] nameB = s.getBytes("UTF-8");
                    if (length + nameB.length == maxLength) {
                        System.arraycopy(nameBytes, 0, real, 0, real.length);
                        return real;
                    } else if (length + nameB.length > maxLength) {//大于24会导致有个字节发不到下位机导致乱码
                        System.arraycopy(nameBytes, 0, real, 0, length);
                        return real;
                    }
                    length += nameB.length;
                }
            }
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return nameBytes;
    }

    public static void crcValue(byte[] value) {
        byte crc = 0;
        for (int i = 0; i < value.length - 1; i++) {
            crc += value[i];
        }
        value[value.length - 1] = (byte) (crc & 0xff);
    }
    public static byte[]  sendHeartPackage(float distance, int space, int rssi) {
        byte[] value = new byte[16];
        byte[] distanceValue = getByteArray(0);

        value[0] = DeviceConst.CMD_heart_package;
        System.arraycopy(distanceValue, 0, value, 1, distanceValue.length);
        ResolveUtil.crcValue(value);
       return value;
    }

    private static byte[] getByteArray(float f) {
        int intbits = Float.floatToIntBits(f);//将float里面的二进制串解释为int整数
        return getByteArray(intbits);
    }

    private static byte[] getByteArray(int i) {
        byte[] b = new byte[4];
        b[3] = (byte) ((i & 0xff000000) >> 24);
        b[2] = (byte) ((i & 0x00ff0000) >> 16);
        b[1] = (byte) ((i & 0x0000ff00) >> 8);
        b[0] = (byte) (i & 0x000000ff);
        return b;
    }
}
